
package me.huha.zhime.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import me.huha.commons.FormatConstants;
import me.huha.spring.concurrent.AsynsService;
import me.huha.spring.concurrent.Responder;
import me.huha.tools.DateUtils;
import me.huha.zhime.company.client.OutPaymentService;
import me.huha.zhime.company.commons.OutPayment;
import me.huha.zhime.entity.AlipayAsynchEntity;
import me.huha.zhime.entity.AlipaySynchEntity;
import me.huha.zhime.entity.OrderInfoEntity;
import me.huha.zhime.entity.OrderInfoEntity.PaymentStatusEnum;
import me.huha.zhime.service.AlipayService;
import me.huha.zhime.service.OrderService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Title: AlipayServiceImpl
 * @Author: Yepx
 * @mail: yepx2013@gmail.com
 * @CreateTime: 2017年10月25日 下午2:51:37
 * @Todo: TODO
 */
@Service("alipayService")
public class AlipayServiceImpl implements AlipayService {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private OrderService orderService;
	@Autowired
	private OutPaymentService outPaymentService;
	@Override
	public Boolean doTradeCallback(Map<String, String> callbackMap, Map<String, String> payStatusMap, OrderInfoEntity orderInfo) {

		//TODO 保存回调数据
		final String notify_time = callbackMap.get("notify_time");			//  通知时间	Date	是	通知的发送时间。格式为yyyy-MM-dd HH:mm:ss	2015-14-27 15:45:58
		final String notify_type = callbackMap.get("notify_type");			//	通知类型	String(64)	是	通知的类型	trade_status_sync
		final String notify_id = callbackMap.get("notify_id");				//	通知校验ID	String(128)	是	通知校验ID	ac05099524730693a8b330c5ecf72da9786
		final String app_id = callbackMap.get("app_id");						//	开发者的app_id	String(32)	是	支付宝分配给开发者的应用Id	2014072300007148
		final String charset = callbackMap.get("charset");					//	编码格式	String(10)	是	编码格式，如utf-8、gbk、gb2312等	utf-8
		final String sign_type = callbackMap.get("sign_type");				//	签名类型	String(10)	是	商户生成签名字符串所使用的签名算法类型，目前支持RSA2和RSA，推荐使用RSA2	RSA2
		final String sign = callbackMap.get("sign");							//	签名	String(256)	是	请参考异步返回结果的验签	601510b7970e52cc63db0f44997cf70e
		final String trade_no = callbackMap.get("trade_no");					//	支付宝交易号	String(64)	是	支付宝交易凭证号	2013112011001004330000121536
		final String out_trade_no = callbackMap.get("out_trade_no");			//	商户订单号	String(64)	是	原支付请求的商户订单号	6823789339978248
		final String out_biz_no = callbackMap.get("out_biz_no");				//	商户业务号	String(64)	否	商户业务ID，主要是退款通知中返回退款申请的流水号	HZRF001
		final String buyer_id = callbackMap.get("buyer_id");					//	买家支付宝用户号	String(16)	否	买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字	2088102122524333
		final String buyer_logon_id = callbackMap.get("buyer_logon_id");		//	买家支付宝账号	String(100)	否	买家支付宝账号	15901825620
		final String seller_id = callbackMap.get("seller_id");				//	卖家支付宝用户号	String(30)	否	卖家支付宝用户号	2088101106499364
		final String seller_email = callbackMap.get("seller_email");			//	卖家支付宝账号	String(100)	否	卖家支付宝账号	zhuzhanghu@alitest.com
		final String trade_status = callbackMap.get("trade_status");			//	交易状态	String(32)	否	交易目前所处的状态，见交易状态说明	TRADE_CLOSED
		final String total_amount = callbackMap.get("total_amount");			//	订单金额	Number(9,2)	否	本次交易支付的订单金额，单位为人民币（元）	20
		final String receipt_amount = callbackMap.get("receipt_amount");		//	实收金额	Number(9,2)	否	商家在交易中实际收到的款项，单位为元	15
		final String invoice_amount = callbackMap.get("invoice_amount");		//	开票金额	Number(9,2)	否	用户在交易中支付的可开发票的金额	10.00
		final String buyer_pay_amount = callbackMap.get("buyer_pay_amount");	//	付款金额	Number(9,2)	否	用户在交易中支付的金额	13.88
		final String point_amount = callbackMap.get("point_amount");			//	集分宝金额	Number(9,2)	否	使用集分宝支付的金额	12.00
		final String refund_fee = callbackMap.get("refund_fee");				//	总退款金额	Number(9,2)	否	退款通知中，返回总退款金额，单位为元，支持两位小数	2.58
		final String  subject = callbackMap.get("subject");					//	订单标题	String(256)	否	商品的标题/交易标题/订单标题/订单关键字等，是请求时对应的参数，原样通知回来	当面付交易
		final String body = callbackMap.get("body");							//	商品描述	String(400)	否	该订单的备注、描述、明细等。对应请求时的body参数，原样通知回来	当面付交易内容
		final String order_create = callbackMap.get("order_create");			//	交易创建时间	Date	否	该笔交易创建的时间。格式为yyyy-MM-dd HH:mm:ss	2015-04-27 15:45:57
		final String order_payment = callbackMap.get("order_payment");		//	交易付款时间	Date	否	该笔交易的买家付款时间。格式为yyyy-MM-dd HH:mm:ss	2015-04-27 15:45:57
		final String order_refund = callbackMap.get("order_refund");			//	交易退款时间	Date	否	该笔交易的退款时间。格式为yyyy-MM-dd HH:mm:ss.S	2015-04-28 15:45:57.320
		final String order_close = callbackMap.get("order_close");			//	交易结束时间	Date	否	该笔交易结束时间。格式为yyyy-MM-dd HH:mm:ss	2015-04-29 15:45:57
		final String fund_bill_list = callbackMap.get("fund_bill_list");		//	支付金额信息	String(512)	否	支付成功的各个渠道金额信息，详见资金明细信息说明	[{"amount":"15.00","fundChannel":"ALIPAYACCOUNT"}]
		final String passback_params = callbackMap.get("passback_params");	//	回传参数	String(512)	否	公共回传参数，如果请求时传递了该参数，则返回给商户时会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝	merchantBizType%3d3C%26merchantBizNo%3d2016010101111
		final String voucher_detail_list = callbackMap.get("voucher_detail_list");	//	优惠券信息	String	否	本交易支付时所使用的所有优惠券信息，详见优惠券信息说明	[{"amount":"0.20","merchantContribute":"0.00","name":"一键创建券模板的券名称","otherContribute":"0.20","type":"ALIPAY_DISCOUNT_VOUCHER","memo":"学生卡8折优惠"]
				

		AlipayAsynchEntity alipayAsynch = new AlipayAsynchEntity(notify_time, notify_type, notify_id, app_id, charset, sign_type, sign, trade_no, out_trade_no, out_biz_no, buyer_id, buyer_logon_id, seller_id, seller_email, 
												trade_status, total_amount, receipt_amount, invoice_amount, buyer_pay_amount, 
												point_amount, refund_fee, subject, body, order_create, order_payment, order_refund, order_close, 
												fund_bill_list, passback_params, voucher_detail_list);
		
		alipayAsynch.createOrUpdate();
		
		//TODO 处理订单业务
		PaymentStatusEnum enum_ = null;
		if("1".equals(payStatusMap.get("payStatus"))){
			enum_ = PaymentStatusEnum.paid;
			
			Date date = null;
			System.out.println(notify_time);
			try {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
				date = sdf.parse(notify_time);
				System.out.println(date);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			final Date date1 = date;
			
			//异步线程 
			AsynsService.asynsService().execute(new Runnable(){

				@Override
				public void run() {
					// TODO Auto-generated method stub
					OutPayment panment = createOutPayment(out_trade_no, trade_no, true, date1);
					outPaymentService.alipayNotify(panment);
				}
				
				}).addResponder(new Responder() {
				
	            @Override
	            public <T> void onResult(T result) {
	                logger.info("this is result.....");
	            }

	            @Override
	            public void onFault(Exception fault) {
	                logger.error(fault.getMessage(), fault);
	            }
	        });
			
			
		}else{
			enum_ = PaymentStatusEnum.paidAbnormal;
			
			OutPayment panment = createOutPayment(out_trade_no, trade_no, false, null);
			outPaymentService.alipayNotify(panment);
		}
		orderService.updateOrderPaymentStatus(orderInfo.getOrderNum(), enum_);
		
		return true;
	}
	
	@Override
	public Boolean doReturnCallback(Map<String, String> callbackMap){
		
		//TODO 保存回调数据
		String notify_time = callbackMap.get("notify_time");			//  通知时间	Date	是	通知的发送时间。格式为yyyy-MM-dd HH:mm:ss	2015-14-27 15:45:58
		String notify_type = callbackMap.get("notify_type");			//	通知类型	String(64)	是	通知的类型	trade_status_sync
		String notify_id = callbackMap.get("notify_id");				//	通知校验ID	String(128)	是	通知校验ID	ac05099524730693a8b330c5ecf72da9786
		String app_id = callbackMap.get("app_id");						//	开发者的app_id	String(32)	是	支付宝分配给开发者的应用Id	2014072300007148
		String charset = callbackMap.get("charset");					//	编码格式	String(10)	是	编码格式，如utf-8、gbk、gb2312等	utf-8
		String sign_type = callbackMap.get("sign_type");				//	签名类型	String(10)	是	商户生成签名字符串所使用的签名算法类型，目前支持RSA2和RSA，推荐使用RSA2	RSA2
		String sign = callbackMap.get("sign");							//	签名	String(256)	是	请参考异步返回结果的验签	601510b7970e52cc63db0f44997cf70e
		String trade_no = callbackMap.get("trade_no");					//	支付宝交易号	String(64)	是	支付宝交易凭证号	2013112011001004330000121536
		String out_trade_no = callbackMap.get("out_trade_no");			//	商户订单号	String(64)	是	原支付请求的商户订单号	6823789339978248
		String out_biz_no = callbackMap.get("out_biz_no");				//	商户业务号	String(64)	否	商户业务ID，主要是退款通知中返回退款申请的流水号	HZRF001
		String buyer_id = callbackMap.get("buyer_id");					//	买家支付宝用户号	String(16)	否	买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字	2088102122524333
		String buyer_logon_id = callbackMap.get("buyer_logon_id");		//	买家支付宝账号	String(100)	否	买家支付宝账号	15901825620
		String seller_id = callbackMap.get("seller_id");				//	卖家支付宝用户号	String(30)	否	卖家支付宝用户号	2088101106499364
		String seller_email = callbackMap.get("seller_email");			//	卖家支付宝账号	String(100)	否	卖家支付宝账号	zhuzhanghu@alitest.com
		String trade_status = callbackMap.get("trade_status");			//	交易状态	String(32)	否	交易目前所处的状态，见交易状态说明	TRADE_CLOSED
		String total_amount = callbackMap.get("total_amount");			//	订单金额	Number(9,2)	否	本次交易支付的订单金额，单位为人民币（元）	20
		String receipt_amount = callbackMap.get("receipt_amount");		//	实收金额	Number(9,2)	否	商家在交易中实际收到的款项，单位为元	15
		String invoice_amount = callbackMap.get("invoice_amount");		//	开票金额	Number(9,2)	否	用户在交易中支付的可开发票的金额	10.00
		String buyer_pay_amount = callbackMap.get("buyer_pay_amount");	//	付款金额	Number(9,2)	否	用户在交易中支付的金额	13.88
		String point_amount = callbackMap.get("point_amount");			//	集分宝金额	Number(9,2)	否	使用集分宝支付的金额	12.00
		String refund_fee = callbackMap.get("refund_fee");				//	总退款金额	Number(9,2)	否	退款通知中，返回总退款金额，单位为元，支持两位小数	2.58
		String  subject = callbackMap.get("subject");					//	订单标题	String(256)	否	商品的标题/交易标题/订单标题/订单关键字等，是请求时对应的参数，原样通知回来	当面付交易
		String body = callbackMap.get("body");							//	商品描述	String(400)	否	该订单的备注、描述、明细等。对应请求时的body参数，原样通知回来	当面付交易内容
		String order_create = callbackMap.get("order_create");			//	交易创建时间	Date	否	该笔交易创建的时间。格式为yyyy-MM-dd HH:mm:ss	2015-04-27 15:45:57
		String order_payment = callbackMap.get("order_payment");		//	交易付款时间	Date	否	该笔交易的买家付款时间。格式为yyyy-MM-dd HH:mm:ss	2015-04-27 15:45:57
		String order_refund = callbackMap.get("order_refund");			//	交易退款时间	Date	否	该笔交易的退款时间。格式为yyyy-MM-dd HH:mm:ss.S	2015-04-28 15:45:57.320
		String order_close = callbackMap.get("order_close");			//	交易结束时间	Date	否	该笔交易结束时间。格式为yyyy-MM-dd HH:mm:ss	2015-04-29 15:45:57
		String fund_bill_list = callbackMap.get("fund_bill_list");		//	支付金额信息	String(512)	否	支付成功的各个渠道金额信息，详见资金明细信息说明	[{"amount":"15.00","fundChannel":"ALIPAYACCOUNT"}]
		String  passback_params = callbackMap.get("passback_params");	//	回传参数	String(512)	否	公共回传参数，如果请求时传递了该参数，则返回给商户时会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝	merchantBizType%3d3C%26merchantBizNo%3d2016010101111
		String  voucher_detail_list = callbackMap.get("voucher_detail_list");	//	优惠券信息	String	否	本交易支付时所使用的所有优惠券信息，详见优惠券信息说明	[{"amount":"0.20","merchantContribute":"0.00","name":"一键创建券模板的券名称","otherContribute":"0.20","type":"ALIPAY_DISCOUNT_VOUCHER","memo":"学生卡8折优惠"]
			

		AlipaySynchEntity alipaySynch = new AlipaySynchEntity(notify_time, notify_type, notify_id, app_id, charset, sign_type, sign, trade_no, out_trade_no, out_biz_no, buyer_id, buyer_logon_id, seller_id, seller_email, 
												trade_status, total_amount, receipt_amount, invoice_amount, buyer_pay_amount, 
												point_amount, refund_fee, subject, body, order_create, order_payment, order_refund, order_close, 
												fund_bill_list, passback_params, voucher_detail_list);
		
		alipaySynch.createOrUpdate();
		
		
		return true;
	}
	
	/**
     * 訂單中心需要返回的數據
     * @param paymentSn
     * @param trade_no
     * @param paymentStatus
     * @param paymentDate
     * @return
     */
    private OutPayment createOutPayment(String paymentSn, String trade_no, Boolean paymentStatus, Date paymentDate){
    	
    	OutPayment payment = new OutPayment();
    	payment.setPaymentSn(paymentSn);
    	payment.setTrade_no(trade_no);
    	payment.setPaymentStatus(paymentStatus);
    	payment.setPaymentDate(paymentDate);
    	return payment;
    }
}
